package com.sinosoft.vaccinetoai.utils;

import java.util.*;

public class CodeNumberUtil {
    private static int count = 0;
    public static final String NUMBERCHAR = "0123456789";

    public static String getCodeNumber(String prefix) {
        if (!StringUtil.isEmpty(prefix)) {
            //可以修改生成随机数的长度，生成想要的长度的条码
            String num = generateNumString(5);
            String st = prefix + num + getUnixTime();
            return st + getCardCheckCode(st);
        }
        return "prefix不能为空";
    }

    /**
     * 生成一个定长的纯数字符串
     * @param length
     * @return 纯数字符串
     */
    private static String generateNumString(int length) {
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(NUMBERCHAR.charAt(random.nextInt(NUMBERCHAR.length())));
        }
        return sb.toString();
    }

    /***
     * 获取当前系统时间戳 并截取后8位
     * @return
     */
    private static String getUnixTime() {
        try {
            Thread.sleep(1);// 快速执行时，休眠10毫秒 防止号码重复
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        count++;
        count = count > 100 ? count % 10 : count;
        return ((System.currentTimeMillis() / 100) + "").substring(5)
                + (count % 10);
    }

    /**
     * 从不含校验位的卡号采用 Luhm 校验算法获得校验位
     * @param nonCheckCodeCardNo
     * @return
     */
    private static char getCardCheckCode(String nonCheckCodeCardNo) {
        if (nonCheckCodeCardNo == null
                || nonCheckCodeCardNo.trim().length() == 0
                || !nonCheckCodeCardNo.matches("\\d+")) {
            // 如果传的不是数据返回N
            return 'N';
        }
        char[] chs = nonCheckCodeCardNo.trim().toCharArray();
        int luhmSum = 0;
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    }

    /**
     * 校验条码是否正确
     * @param code
     * @return
     */
    public static boolean checkCode(String code) {
        char bit = getCardCheckCode(code.substring(0, code.length() - 1));
        if (bit == 'N') {
            return false;
        }
        return code.charAt(code.length() - 1) == bit;
    }

    public static void main(String[] args) {
        int i = 0;
        Map<String,String> map = new HashMap<>();
        Long totalStart = System.currentTimeMillis();
        Long start = totalStart;

        while (i < 10000){
            map.put(getCodeNumber("001"),"1");
            i++;
            if(i%100 == 0){
                Long end = System.currentTimeMillis();
                System.out.println("已经生成"+map.size()+"条码 " + "这次耗时 " + (end-start) + "毫秒");
                start = System.currentTimeMillis();
            }

        }
        Long end = System.currentTimeMillis();
        System.out.println("已经生成"+map.size()+"条码 " + "总耗时 " + (end-totalStart) + "毫秒");

        System.out.println(map.size());

        for(String code: map.keySet()){
            if(!checkCode(code)){
                System.out.println("code 异常" + code);
            }

        }
        List<String> list =  new ArrayList(map.keySet());
       for(i=0;i<10;i++){
           System.out.println(list.get(i));
       }
        String code = "0010706763404002";
        if(!checkCode("code")){
            System.out.println("code 异常" + code);
        }
        code = "0011231862427770";
        if(!checkCode("code")){
            System.out.println("code 异常" + code);
        }
         code = "0015211762402350";
        if(!checkCode("code")){
            System.out.println("code 异常" + code);
        }
        code = "0013242562401751";
        if(!checkCode("code")){
            System.out.println("code 异常" + code);
        }
    }
}
